package com.cennavi.minenavidemo.presenter;

import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;

import com.cennavi.minenavidemo.utils.Config;
import com.cennavi.minenavidemo.utils.MineNaviProgressManager;
import com.cennavi.minenavidemo.utils.ScreenUtil;
import com.minedata.minenavi.mapdal.DataPreference;
import com.minedata.minenavi.mapdal.GpsTracker;
import com.minedata.minenavi.mapdal.PoiFavorite;
import com.minedata.minenavi.navi.ArrowInfo;
import com.minedata.minenavi.navi.GuidanceText;
import com.minedata.minenavi.navi.GuidanceTextGenerator;
import com.minedata.minenavi.navi.HadRouteDetailBrowser;
import com.minedata.minenavi.navi.NaviProgressData;
import com.minedata.minenavi.navi.NaviProgressMonitor;
import com.minedata.minenavi.navi.NaviSession;
import com.minedata.minenavi.navi.NaviSessionData;
import com.minedata.minenavi.navi.NaviSpeaker;
import com.minedata.minenavi.navi.RouteBase;
import com.minedata.minenavi.navi.RouteCollection;
import com.minedata.minenavi.navi.RouteDetailItem;
import com.minedata.minenavi.navi.RoutePlan;
import com.minedata.minenavi.navi.RouterErrorInfo;
import com.minedata.minenavi.navi.SmoothNaviData;
import com.minedata.minenavi.navi.TmcSections;
import com.minedata.minenavi.navi.VehicleInfo;

import java.util.ArrayList;
import java.util.List;

public class NaviPresenter implements GpsTracker.GPSEventHandler {
    private static final String TAG = "[NaviPresenter]";
    private final float SPEED_LIMIT_MAX = 5.0f;
    private final float SPEED_LIMIT_MIN = 1.0f;
    private final float SPEED_CHANGE_STEP = 2.0f;

    private Context mContext;
    private MapPresenter mMapPresenter;
    private NaviSession mNaviSession;
    private GpsTracker mGpsTracker = null;
    private GuidanceTextGenerator mGuidanceTextGenerator;
    private MineNaviProgressManager mMineNaviProgressManager;
    ;
    // 路线详情加载器
    private HadRouteDetailBrowser mHadRouteDetailBrowser = null;
    // 路线详情数据集合
    private ArrayList<RouteDetailItem> mRouteDetailItems = null;
    // 路线规划结果集
    private RouteCollection mRouteCollection = null;
    private RouteBase mRouteBase = null;
    // 起点
    private String mStartName = "";
    private Point mStartPoint = new Point();
    // 终点
    private String mEndName = "";
    private Point mEndPoint = new Point();
    //是否正在导航
    private boolean mIsInNavigation = false;
    // 路线规划类型
    private int mRouteType = 0;
    private int mNaviIndex = 0;
    private OnNaviPresenterListener mOnNaviPresenterListener;

    public interface OnNaviPresenterListener {

        void onDataUpdated(NaviProgressData naviProgressData);

        void onTiBarUpdated(final TmcSections tmcSections);

        void onTextChanged(GuidanceText guidanceText);

        void onDistanceChanged(int distance);

        void onRouteDetailBrowserLoaded(List<RouteDetailItem> routeDetailItems);

        void onCalculateRouteSuccess(RouteBase routeBase);

        void onCalculateRouteFailed(String msg);

        void onArriveDestination();

        void onRerouteFailed(String msg);

        void onNaviBegin();

        void onSimNaviBegin();

        void onSimNaviEnd();

        void onTracking(float ratio);

        void onGpsConnected();
    }

    private NaviPresenter() {
    }

    private static class SingletonHolder {
        public static final NaviPresenter instance = new NaviPresenter();
    }

    public static NaviPresenter getInstance() {
        return SingletonHolder.instance;
    }

    public void setOnNaviPresenterListener(OnNaviPresenterListener onNaviPresenterListener) {
        this.mOnNaviPresenterListener = onNaviPresenterListener;
    }

    public void init(Context context) {
        // 自定义语音
        NaviSpeaker.enqueue("欢迎使用导航");
        mContext = context;
        mMapPresenter = MapPresenter.getInstance();

        mNaviSession = NaviSession.getInstance();
        try {
            NaviSession.getInstance().enableSound(true);
            NaviSession.getInstance()
                    .setDataPreference(
                            Config.online ? DataPreference.preferOnline : DataPreference.preferOffline);
        } catch (Exception e) {
            e.printStackTrace();
        }

        NaviProgressMonitor.getInstance().addListener(mNaviProgressUpdatedListener);
        mGuidanceTextGenerator = new GuidanceTextGenerator();
        mGuidanceTextGenerator.addListener(mGuidanceTextGeneratorChangedListener);
        mMineNaviProgressManager = new MineNaviProgressManager();
        mMineNaviProgressManager.addOnNaviPresenterListener(mOnMineNaviProgressListener);

        if (mGpsTracker == null) {
            mGpsTracker = GpsTracker.getInstance();
        }

        mGpsTracker.registerGpsTrackerListener(this, null);
    }

    public void clean() {
        //退出当前页面的时候清理GPS定位监听
        if (mGpsTracker != null) {
            mGpsTracker.unregisterGpsTrackerListener();
        }

        mNaviSession.removeMineNaviListener(mMineNaviProgressManager);
        NaviProgressMonitor.getInstance().removeListener(mNaviProgressUpdatedListener);
        mGuidanceTextGenerator.removeListener(mGuidanceTextGeneratorChangedListener);
    }

    public void setRouteType(int routeType) {
        mRouteType = routeType;
    }

    public void setNaviIndex(int naviIndex) {
        mNaviIndex = naviIndex;
    }

    public int getNaviIndex() {
        return mNaviIndex;
    }

    public void setInNavigation(boolean inNavigation) {
        mIsInNavigation = inNavigation;
    }

    public boolean isInNavigation() {
        return mIsInNavigation;
    }

    public void switchDataPreference() {
        if (mNaviSession.getDataPreference() == DataPreference.onlineOnly) {
            mNaviSession.setDataPreference(DataPreference.offlineOnly);
        } else {
            mNaviSession.setDataPreference(DataPreference.onlineOnly);
        }
    }

    public RouteBase getRouteBase() {
        return mRouteBase;
    }

    /**
     * 导航
     */
    public void startNavi() {
        mIsInNavigation = true;
        mMapPresenter.drawStartAndEndMyLocationStyle(mStartPoint, mEndPoint);
        mMapPresenter.drawNavingCar(mStartPoint);
        mMapPresenter.showDestinationLabel(mRouteBase);

        // 点击导航按钮 恢复导航
        if (mNaviSession.isNaviPaused()) {
            NaviSpeaker.enqueue("恢复导航");
            mNaviSession.resumeNavi();
        } else {
            NaviSpeaker.enqueue("导航开始");
            mNaviSession.takeRoute(mRouteBase);
        }
    }

    public void startSimNavi() {
        mIsInNavigation = true;
        mMapPresenter.drawStartAndEndMyLocationStyle(mStartPoint, mEndPoint);
        mMapPresenter.drawNavingCar(mStartPoint);
        mMapPresenter.showDestinationLabel(mRouteBase);

        NaviSpeaker.stop();
        mNaviSession.takeRouteQuietly(mRouteBase);
        // 设置速度
        mNaviSession.setEmulatorNaviSpeed(3.0f);
        // 开始导航
        mNaviSession.startSimulation();
    }

    public void pauseNavi() {
        if (!mNaviSession.isNaviPaused()) {
            mNaviSession.pauseNavi();
        }
    }

    public void pauseSimNavi() {
        if (mNaviSession.isSimulationPaused()) {
            mNaviSession.resumeSimulation();
        } else {
            mNaviSession.pauseSimulation();
        }
    }

    public boolean isSimulationPaused() {
        return mNaviSession.isSimulationPaused();
    }

    public void faster() {
        float speed = mNaviSession.getSimulationSpeed();

        if (speed < SPEED_LIMIT_MAX) {
            speed += SPEED_CHANGE_STEP;
            mNaviSession.setEmulatorNaviSpeed(speed);
        }
    }

    public void slower() {
        float speed = mNaviSession.getSimulationSpeed();
        if (speed > SPEED_LIMIT_MIN) {
            speed -= SPEED_CHANGE_STEP;
            mNaviSession.setEmulatorNaviSpeed(speed);
        }
    }

    public void calculateRoute(String startName, String endName, Point startPoint, Point endPoint) {
        mStartName = startName;
        mStartPoint = startPoint;
        mEndName = endName;
        mEndPoint = endPoint;
        List<PoiFavorite> wayPoints = new ArrayList<>();
        //        mPassName = "鸟巢";
        //        mPassPoint = Tools.latLngToPoint(new LatLng(39.99300, 116.39524));
        //        wayPoints.add(new PoiFavorite(mPassPoint, mPassName));

        PoiFavorite newstartPoint = new PoiFavorite(startPoint, startName);
        PoiFavorite newendPoint = new PoiFavorite(endPoint, endName);

        if (mRouteType == 0) {
            RoutePlan routePlan = new RoutePlan();
            routePlan.setRoutePreference(mNaviIndex);
            routePlan.setTransportationType(RoutePlan.TransportationType.car);
//            mNaviSession.calculateDriveRoute(newstartPoint, wayPoints, newendPoint, info, mNaviIndex, NaviSession.RouteMethod.multipleResult);
            mNaviSession.calculateDriveRoute(newstartPoint, wayPoints, newendPoint, routePlan, NaviSession.RouteMethod.multipleResult);
//          RoutePlan routePlan = new RoutePlan("{" +
//                  "        \"routePoints\": [" +
//                  "            {" +
//                  "                \"type\": 1," +
//                  "                \"position\": \"12354878,4183434\"," +
//                  "                \"entryPoint\": \"12354878,4183434\"," +
//                  "                \"name\": \"test1\"" +
//                  "            }," +
//                  "            {" +
//                  "                \"type\": 1," +
//                  "                \"position\": \"12354126,4177913\"," +
//                  "                \"entryPoint\": \"12354126,4177913\"," +
//                  "                \"name\": \"test2\"" +
//                  "            }" +
//                  "        ]" +
//                  "    }");
//          mNaviSession.calculateDriveRoute(routePlan,"{\"result\":[{\"route\":{\"dur\":1029,\"trafficSpeeds\":\"28x9,28x15,30x17,46x21,36,39x5,39x3,?x6,23x3,23x2,?x6,37x2,38,45x6,?x12\",\"cost\":21902,\"traits\":\"recommended\",\"naviHead\":{\"ver\":\"2.4.57\",\"code\":100,\"tmcTm\":\"2020/12/2811:41:00\"},\"fee\":0,\"rmd\":[{\"eI\":1,\"pos\":\"XNAYF+xA0Ac=\",\"sI\":0,\"flags\":\"T\",\"tnTy\":1,\"dis\":37},{\"eI\":5,\"laneModel\":{\"driveArrow\":2,\"lanes\":[{\"arrow\":2,\"shouldUse\":1},{\"arrow\":7,\"shouldUse\":1}],\"laneNumber\":2},\"pos\":\"yMoYF+hA0Ac=\",\"sI\":3,\"flags\":\"T\",\"tnTy\":1,\"dis\":178},{\"eI\":10,\"laneModel\":{\"driveArrow\":2,\"lanes\":[{\"arrow\":6,\"shouldUse\":1},{\"arrow\":7,\"shouldUse\":1}],\"laneNumber\":2},\"pos\":\"lMIYF8RA0Ac=\",\"sI\":8,\"flags\":\"T\",\"tnTy\":1,\"dis\":409},{\"eI\":14,\"laneModel\":{\"driveArrow\":2,\"lanes\":[{\"arrow\":6,\"shouldUse\":1},{\"arrow\":2,\"shouldUse\":1},{\"arrow\":5,\"shouldUse\":0}],\"laneNumber\":3},\"pos\":\"4LwYF7hA0Ac=\",\"sI\":12,\"flags\":\"T\",\"tnTy\":1,\"dis\":557},{\"eI\":68,\"laneModel\":{\"driveArrow\":2,\"lanes\":[{\"arrow\":2,\"shouldUse\":1},{\"arrow\":2,\"shouldUse\":1},{\"arrow\":7,\"shouldUse\":1},{\"arrow\":0,\"shouldUse\":0}],\"laneNumber\":4},\"pos\":\"aP4YF2BU0Ac=\",\"sI\":67,\"tnTy\":10,\"dis\":4093}],\"segm\":[{\"tmcLv\":1,\"pr\":5,\"niId\":\"665415*\",\"usage\":2,\"bridgeName\":\"\",\"spl\":60,\"dis\":37,\"shPos\":\"BNIYF/RA0AerCw==\",\"id\":-665415,\"trafficLight\":1,\"tunnelName\":\"\",\"laneCount\":2,\"nm\":\"国家体育场北路\"},{\"niId\":\"112138227*\",\"shPos\":\"XNAYF+xA0AczAZsB\",\"id\":-112138227,\"dis\":43},{\"niId\":\"112138226*\",\"shPos\":\"lM4YF+xA0AejBw==\",\"id\":-112138226,\"dis\":34},{\"niId\":\"665403*\",\"shPos\":\"9MwYF+hA0AcuAwE=\",\"id\":-665403,\"trafficLight\":1,\"dis\":64},{\"niId\":\"685150*\",\"usage\":4,\"shPos\":\"yMoYF+hA0AcrAQ==\",\"id\":-685150,\"trafficLight\":1,\"dis\":9,\"laneCount\":1},{\"niId\":\"707042*\",\"usage\":2,\"shPos\":\"oMoYF+hA0AcGBQ8=\",\"id\":-707042,\"dis\":110,\"laneCount\":2},{\"niId\":\"707047*\",\"shPos\":\"nMYYF9xA0AcaAw8=\",\"id\":-707047,\"dis\":60},{\"niId\":\"16571200*\",\"shPos\":\"hMQYF9BA0AdHBw==\",\"id\":-16571200,\"dis\":15},{\"niId\":\"16571199*\",\"shPos\":\"QMQYF8xA0AevCw==\",\"id\":-16571199,\"trafficLight\":1,\"dis\":37},{\"niId\":\"668607*\",\"usage\":4,\"shPos\":\"lMIYF8RA0AcnAQ==\",\"id\":-668607,\"trafficLight\":1,\"dis\":8,\"laneCount\":1},{\"niId\":\"49043775*\",\"usage\":2,\"shPos\":\"cMIYF8RA0AdnAQ==\",\"id\":-49043775,\"spl\":70,\"dis\":21,\"laneCount\":3},{\"niId\":\"49043774*\",\"shPos\":\"DMIYF8RA0AfjBw==\",\"id\":-49043774,\"dis\":48},{\"niId\":\"49043771*\",\"shPos\":\"LMAYF8BA0AdOAws=\",\"id\":-49043771,\"trafficLight\":1,\"dis\":71},{\"niId\":\"568837*\",\"usage\":4,\"shPos\":\"4LwYF7hA0AczAQ==\",\"id\":-568837,\"trafficLight\":1,\"spl\":60,\"dis\":10,\"laneCount\":1,\"nm\":\"\"},{\"niId\":\"49043769\",\"usage\":2,\"shPos\":\"sLwYF7hA0AcKAws=\",\"id\":49043769,\"dis\":56,\"laneCount\":2,\"nm\":\"科学园南里东街\"},{\"niId\":\"19361382\",\"shPos\":\"qLoYF7BA0AcqAws=\",\"id\":19361382,\"dis\":63},{\"niId\":\"19361383\",\"shPos\":\"gLgYF6hA0AcrAQ==\",\"id\":19361383,\"dis\":9},{\"niId\":\"591261\",\"shPos\":\"WLgYF6hA0AcuAwc=\",\"id\":591261,\"dis\":64},{\"niId\":\"32234261\",\"shPos\":\"LLYYF6RA0Af7Bw==\",\"id\":32234261,\"dis\":53},{\"niId\":\"32234262\",\"shPos\":\"NLQYF6BA0AdTAeMH\",\"id\":32234262,\"dis\":65},{\"niId\":\"671681\",\"shPos\":\"BLIYF5xA0AcmAwdXBw==\",\"id\":671681,\"dis\":80},{\"niId\":\"680271\",\"shPos\":\"jK4YF5RA0Ad2AxM=\",\"id\":680271,\"dis\":79},{\"niId\":\"679574\",\"shPos\":\"GKwYF4RA0AdrB4MLqxs=\",\"id\":679574,\"dis\":86},{\"niId\":\"679575\",\"shPos\":\"iKgYF2BA0AcnBw==\",\"id\":679575,\"trafficLight\":1,\"dis\":8},{\"niId\":\"19633482*\",\"usage\":1,\"shPos\":\"ZKgYF1xA0AcJDAM=\",\"id\":-19633482,\"spl\":40,\"dis\":74,\"laneCount\":1,\"nm\":\"科学园南里中街\"},{\"niId\":\"80528604*\",\"shPos\":\"bKgYF2hC0AcBJQ==\",\"id\":-80528604,\"dis\":10},{\"niId\":\"605016979*\",\"usage\":2,\"shPos\":\"bKgYF4xC0AcVPQ==\",\"id\":-605016979,\"spl\":50,\"dis\":17},{\"niId\":\"606017140*\",\"shPos\":\"gKgYF8hC0AcJGQVp\",\"id\":-606017140,\"dis\":36},{\"niId\":\"80528608*\",\"shPos\":\"jKgYF0hE0AcFyQ==\",\"id\":-80528608,\"dis\":56},{\"niId\":\"80528605*\",\"shPos\":\"kKgYFxBG0AcF8Q==\",\"id\":-80528605,\"dis\":67},{\"niId\":\"80528957*\",\"shPos\":\"lKgYFwBI0AcBHQ==\",\"id\":-80528957,\"dis\":8},{\"niId\":\"80528956*\",\"shPos\":\"lKgYFxxI0AcFIQ==\",\"id\":-80528956,\"dis\":9},{\"niId\":\"104661611*\",\"shPos\":\"mKgYFzxI0AcBEQ==\",\"id\":-104661611,\"dis\":4},{\"niId\":\"104661609*\",\"shPos\":\"mKgYF0xI0AcFlQ==\",\"id\":-104661609,\"dis\":41},{\"niId\":\"104661607*\",\"shPos\":\"nKgYF+BI0AcBURs1\",\"id\":-104661607,\"dis\":38},{\"niId\":\"610062721*\",\"usage\":1,\"shPos\":\"hKgYF2RK0AcBIQ==\",\"id\":-610062721,\"spl\":40,\"dis\":9},{\"niId\":\"607063077*\",\"shPos\":\"hKgYF4RK0AcBEQ==\",\"id\":-607063077,\"dis\":4},{\"niId\":\"520063321*\",\"shPos\":\"hKgYF5RK0AcBIQ==\",\"id\":-520063321,\"dis\":9},{\"niId\":\"598335*\",\"shPos\":\"hKgYF7RK0AcFNQ==\",\"id\":-598335,\"dis\":14},{\"niId\":\"720068*\",\"shPos\":\"iKgYF+hK0AcBPQ==\",\"id\":-720068,\"dis\":17,\"laneCount\":3},{\"niId\":\"720067*\",\"shPos\":\"iKgYFyRM0AcBCQmh\",\"id\":-720067,\"trafficLight\":1,\"dis\":47},{\"niId\":\"734020\",\"usage\":2,\"shPos\":\"kKgYF8xM0AcZAQ==\",\"id\":734020,\"spl\":60,\"dis\":5,\"nm\":\"大屯路\"},{\"niId\":\"734022\",\"shPos\":\"qKgYF8xM0AdJBQ==\",\"id\":734022,\"dis\":15},{\"niId\":\"70243335\",\"shPos\":\"8KgYF9BM0AcpAYkF\",\"id\":70243335,\"dis\":37},{\"niId\":\"70243336\",\"shPos\":\"oKoYF9RM0AclAT0FKQEZAQ==\",\"id\":70243336,\"dis\":34},{\"niId\":\"85906905\",\"shPos\":\"QKwYF9hM0AcEAwk=\",\"id\":85906905,\"dis\":55},{\"niId\":\"29774543\",\"shPos\":\"RK4YF+BM0AclAQ==\",\"id\":29774543,\"dis\":8},{\"niId\":\"29774544\",\"shPos\":\"aK4YF+BM0AcYAw0=\",\"id\":29774544,\"dis\":60},{\"niId\":\"574339\",\"shPos\":\"gLAYF+xM0AftCdQDEbADCQ==\",\"id\":574339,\"dis\":242},{\"niId\":\"12710058\",\"shPos\":\"8LgYFwxO0AcYAwlVAQ==\",\"id\":12710058,\"tunnel\":1,\"tunnelName\":\"大屯路隧道\",\"dis\":78},{\"niId\":\"86035424\",\"shPos\":\"XLwYFxRO0ActBY0FFAUNJQWxBW0FfAUVdQUdBS0FlQlBBVgDCTkBoQU9Aa0JUQEpBXgDCYUBCQUYAwU=\",\"id\":86035424,\"tunnel\":1,\"dis\":806},{\"niId\":\"86035425\",\"shPos\":\"INoYF4hO0AchAWEFJQFxBVEBvAMN\",\"id\":86035425,\"tunnel\":1,\"dis\":170},{\"niId\":\"12710056\",\"shPos\":\"QOAYF5xO0AdpBfUJRQE8AwUpBV0BJQUNAQ==\",\"id\":12710056,\"tunnel\":1,\"dis\":194},{\"niId\":\"13248195\",\"shPos\":\"0OYYF7RO0AcxAQ==\",\"id\":13248195,\"tunnel\":1,\"dis\":10},{\"niId\":\"13248196\",\"shPos\":\"AOgYF7RO0Ad9BYUF\",\"id\":13248196,\"tunnel\":1,\"dis\":55},{\"niId\":\"565093\",\"shPos\":\"AOoYF7xO0AdsBRm8BRE=\",\"id\":565093,\"tunnelName\":\"\",\"dis\":282},{\"niId\":\"734028\",\"shPos\":\"KPQYF+RO0AetBQ==\",\"id\":734028,\"dis\":37},{\"niId\":\"734029\",\"shPos\":\"1PQYF+hO0AchAQ==\",\"id\":734029,\"dis\":7},{\"niId\":\"86035107\",\"shPos\":\"9PQYF+hO0AeBBQQDBQ==\",\"id\":86035107,\"dis\":83,\"laneCount\":4},{\"niId\":\"86035108\",\"shPos\":\"ePgYF/BO0AdhBZUB5Q0=\",\"id\":86035108,\"dis\":101},{\"niId\":\"720018\",\"shPos\":\"UPwYFwBQ0AexCQ==\",\"id\":720018,\"trafficLight\":1,\"dis\":38,\"laneCount\":5},{\"niId\":\"582791\",\"usage\":4,\"shPos\":\"AP4YFwhQ0AcVCQ==\",\"id\":582791,\"trafficLight\":1,\"dis\":7,\"laneCount\":1},{\"pr\":3,\"niId\":\"585592\",\"shPos\":\"FP4YFxBQ0AcpGQ==\",\"id\":585592,\"trafficLight\":1,\"dis\":15},{\"niId\":\"585594*\",\"shPos\":\"PP4YFyhQ0ActGQ==\",\"id\":-585594,\"trafficLight\":1,\"spl\":70,\"dis\":14,\"nm\":\"安立路\"},{\"niId\":\"720027\",\"usage\":2,\"prm\":1,\"shPos\":\"aP4YF0BQ0AcBWQ==\",\"id\":720027,\"dis\":24,\"laneCount\":4},{\"niId\":\"32159381\",\"shPos\":\"aP4YF5hQ0AcB5Q==\",\"id\":32159381,\"dis\":63},{\"niId\":\"32159382\",\"shPos\":\"aP4YF3xS0AcBWQEV\",\"id\":32159382,\"dis\":30},{\"niId\":\"70243338\",\"shPos\":\"aP4YF+hS0AcBeQ==\",\"id\":70243338,\"dis\":33},{\"niId\":\"565080\",\"shPos\":\"aP4YF2BU0AcBwQ==\",\"id\":565080,\"dis\":53,\"laneCount\":5},{\"niId\":\"720012\",\"shPos\":\"aP4YFyBW0AcFFAM=\",\"id\":720012,\"dis\":77},{\"niId\":\"720013\",\"shPos\":\"bP4YFzRY0AcFlQ==\",\"id\":720013,\"trafficLight\":1,\"dis\":41},{\"pr\":5,\"niId\":\"582786\",\"usage\":4,\"prm\":0,\"shPos\":\"cP4YF8hY0AclBQ==\",\"id\":582786,\"trafficLight\":1,\"spl\":40,\"dis\":8,\"laneCount\":1,\"nm\":\"大屯北路\"},{\"niId\":\"502128414\",\"usage\":1,\"shPos\":\"lP4YF8xY0AfxJQ==\",\"id\":502128414,\"dis\":52,\"laneCount\":2},{\"niId\":\"601128597\",\"shPos\":\"hAAaF/BY0AeJFQ==\",\"id\":601128597,\"dis\":29},{\"niId\":\"729644\",\"shPos\":\"DAIaFwRa0AcZAQ==\",\"id\":729644,\"dis\":5,\"laneCount\":1},{\"niId\":\"14226814\",\"shPos\":\"JAIaFwRa0Ac9CQ==\",\"id\":14226814,\"dis\":13},{\"niId\":\"14226815\",\"shPos\":\"YAIaFwxa0AfkA00=\",\"id\":14226815,\"dis\":105},{\"niId\":\"32909644\",\"usage\":4,\"shPos\":\"RAYaF1ha0AclAQ==\",\"id\":32909644,\"spl\":50,\"dis\":8},{\"niId\":\"32909648\",\"shPos\":\"aAYaF1ha0AclBw==\",\"id\":32909648,\"dis\":8},{\"niId\":\"32909649\",\"usage\":2,\"shPos\":\"jAYaF1Ra0AdgBWE=\",\"id\":32909649,\"dis\":132},{\"niId\":\"32909619\",\"shPos\":\"7AoaF7Ra0AdwBUU=\",\"id\":32909619,\"dis\":134},{\"niId\":\"32909621\",\"shPos\":\"XBAaF/ha0AdMAxk=\",\"id\":32909621,\"dis\":71},{\"pr\":6,\"niId\":\"78383139\",\"usage\":4,\"shPos\":\"qBIaFxBc0AcBKQ==\",\"id\":78383139,\"spl\":60,\"dis\":11,\"nm\":\"\"},{\"niId\":\"721277\",\"usage\":1,\"shPos\":\"qBIaFzhc0AcBNQ==\",\"id\":721277,\"dis\":14,\"laneCount\":2},{\"niId\":\"73522417\",\"shPos\":\"qBIaF2xc0AcFJAM=\",\"id\":73522417,\"dis\":81},{\"niId\":\"73522418\",\"shPos\":\"rBIaF5Be0AcBYQ==\",\"id\":73522418,\"dis\":27},{\"niId\":\"73522405\",\"shPos\":\"rBIaF/Be0AcPvAM=\",\"id\":73522405,\"dis\":123},{\"niId\":\"73522406\",\"shPos\":\"oBIaF6xi0AcH6Q==\",\"id\":73522406,\"dis\":64,\"laneCount\":1},{\"pr\":3,\"niId\":\"719991\",\"usage\":2,\"shPos\":\"nBIaF5Rk0Ad8AwfRAQ==\",\"id\":719991,\"spl\":70,\"dis\":125,\"laneCount\":3,\"nm\":\"科荟路\"},{\"niId\":\"719992\",\"shPos\":\"6BYaF5Bk0Ad9Bw==\",\"id\":719992,\"trafficLight\":1,\"dis\":26},{\"niId\":\"584123*\",\"usage\":4,\"shPos\":\"ZBgaF4xk0AdZGQ==\",\"id\":-584123,\"trafficLight\":1,\"spl\":60,\"dis\":27,\"laneCount\":1,\"nm\":\"\"},{\"niId\":\"574056\",\"shPos\":\"vBgaF6Rk0AchCQ==\",\"id\":574056,\"trafficLight\":1,\"spl\":70,\"dis\":9,\"nm\":\"北苑路\"},{\"niId\":\"574054\",\"usage\":2,\"shPos\":\"3BgaF6xk0AcTVQ==\",\"id\":574054,\"dis\":24,\"laneCount\":4},{\"niId\":\"70243343\",\"shPos\":\"zBgaFwBm0AcncAMHSQ==\",\"id\":70243343,\"dis\":123},{\"niId\":\"70243344\",\"shPos\":\"pBgaF7ho0AcX4QFFBUE=\",\"id\":70243344,\"dis\":99},{\"niId\":\"19376689\",\"shPos\":\"lBgaFxxs0AcVJAMNqQ2JcfwD\",\"id\":19376689,\"dis\":309},{\"niId\":\"580184\",\"shPos\":\"MBoaF2x00AdRgAM=\",\"id\":580184,\"dis\":108},{\"pr\":6,\"niId\":\"574060\",\"usage\":1,\"shPos\":\"gBoaF+x20AeFB5UBWQGhATkH\",\"id\":574060,\"spl\":40,\"dis\":125,\"laneCount\":1,\"nm\":\"双拥路\"},{\"niId\":\"574061\",\"shPos\":\"yB4aF+R20AeJAYkBFAMHuQtNB2ELRQc=\",\"id\":574061,\"dis\":207},{\"niId\":\"603235\",\"shPos\":\"lCYaF8h20AdNB40LVQE=\",\"id\":603235,\"dis\":64},{\"niId\":\"88026226\",\"shPos\":\"wCgaF7x20Ac9B4UHiQs=\",\"id\":88026226,\"dis\":70},{\"niId\":\"88026227\",\"shPos\":\"CCwaF6x20AeVBdEBaQk5BXEBaQcpAX0H\",\"id\":88026227,\"dis\":191},{\"niId\":\"14226851\",\"shPos\":\"iDIaF7R20AcVAQ0B\",\"id\":14226851,\"dis\":7},{\"niId\":\"14226852\",\"shPos\":\"qDIaF7R20Ae1B6kHlQGJBw==\",\"id\":14226852,\"dis\":135},{\"niId\":\"88026229\",\"shPos\":\"IDgaF6h20AcNATEB\",\"id\":88026229,\"dis\":13},{\"niId\":\"581314\",\"usage\":4,\"shPos\":\"XDgaF6h20Ac5AQ==\",\"id\":581314,\"dis\":12},{\"tmcLv\":0,\"pr\":8,\"niId\":\"606251\",\"usage\":2,\"shPos\":\"lDgaF6h20AcBHQER\",\"id\":606251,\"spl\":5,\"dis\":12,\"nm\":\"\"},{\"niId\":\"584221\",\"shPos\":\"lDgaF9R20AcFUQEt\",\"id\":584221,\"spl\":15,\"dis\":34},{\"niId\":\"581318\",\"shPos\":\"mDgaF1B40AcJOQERBREJFQUJ\",\"id\":581318,\"dis\":33}],\"dis\":6902,\"mnv\":[{\"evRecord\":{\"hintPos\":\"ZKgYF1xA0Ac=\",\"bk\":\"3546059279879669\",\"dir\":\"14514534600068597\",\"type\":1},\"turnIconModel\":\"JaeiM\",\"pos\":\"ZKgYF1xA0Ac=\",\"sSI\":23,\"turnAngle\":-99,\"tnTy\":3,\"eSI\":24,\"hasTrafficLight\":true,\"dis\":1130,\"nm\":\"科学园南里中街\"},{\"turnIconModel\":\"JaeiMn\",\"laneModel\":{\"driveArrow\":5,\"lanes\":[{\"arrow\":4,\"shouldUse\":0},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":5,\"shouldUse\":1}],\"laneNumber\":3},\"pos\":\"kKgYF8xM0Ac=\",\"sSI\":40,\"turnAngle\":-89,\"tnTy\":14,\"eSI\":41,\"hasTrafficLight\":true,\"dis\":1590,\"nm\":\"大屯路\"},{\"turnIconModel\":\"JaDeim\",\"laneModel\":{\"driveArrow\":4,\"lanes\":[{\"arrow\":4,\"shouldUse\":1},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":5,\"shouldUse\":0}],\"laneNumber\":5},\"mnTy\":3,\"pos\":\"AP4YFwhQ0Ac=\",\"sSI\":60,\"turnAngle\":87,\"tnTy\":2,\"eSI\":64,\"hasTrafficLight\":true,\"dis\":3907,\"nm\":\"安立路\"},{\"evRecord\":{\"hintPos\":\"bP4YFzRY0Ac=\",\"bk\":\"101795852623682\",\"dir\":\"11070271172812610\",\"type\":1},\"turnIconModel\":\"JadiL\",\"laneModel\":{\"driveArrow\":5,\"lanes\":[{\"arrow\":4,\"shouldUse\":0},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":7,\"shouldUse\":1}],\"laneNumber\":5},\"pos\":\"cP4YF8hY0Ac=\",\"sSI\":70,\"turnAngle\":-78,\"tnTy\":3,\"eSI\":72,\"hasTrafficLight\":true,\"dis\":4264,\"nm\":\"大屯北路\"},{\"turnIconModel\":\"JaEi\",\"pos\":\"qBIaFxBc0Ac=\",\"sSI\":81,\"turnAngle\":84,\"tnTy\":2,\"eSI\":83,\"dis\":4829},{\"endOfRoad\":1,\"turnIconModel\":\"JaeM\",\"laneModel\":{\"driveArrow\":5,\"lanes\":[{\"arrow\":5,\"shouldUse\":1}],\"laneNumber\":1},\"pos\":\"nBIaF5Rk0Ac=\",\"sSI\":87,\"turnAngle\":-92,\"tnTy\":3,\"eSI\":88,\"dis\":5149,\"nm\":\"科荟路\"},{\"evRecord\":{\"hintPos\":\"6BYaF5Bk0Ac=\",\"bk\":\"101795770229189\",\"dir\":\"3757954210292165\",\"type\":1},\"turnIconModel\":\"JaEim\",\"laneModel\":{\"driveArrow\":4,\"lanes\":[{\"arrow\":4,\"shouldUse\":1},{\"arrow\":2,\"shouldUse\":0},{\"arrow\":7,\"shouldUse\":0}],\"laneNumber\":3},\"pos\":\"ZBgaF4xk0Ac=\",\"sSI\":89,\"turnAngle\":99,\"tnTy\":2,\"eSI\":92,\"hasTrafficLight\":true,\"dis\":5300,\"nm\":\"北苑路\"},{\"turnIconModel\":\"JaiM\",\"pos\":\"gBoaF+x20Ac=\",\"sSI\":96,\"turnAngle\":-83,\"tnTy\":3,\"eSI\":97,\"dis\":5999,\"nm\":\"双拥路\"},{\"turnIconModel\":\"JaEi\",\"pos\":\"XDgaF6h20Ac=\",\"sSI\":104,\"turnAngle\":90,\"tnTy\":2,\"eSI\":106,\"dis\":6811},{\"turnIconModel\":\"JaDh\",\"mnTy\":11,\"nc\":0,\"pos\":\"sDgaF8R40Ac=\",\"sSI\":108,\"turnAngle\":0,\"tnTy\":0,\"eSI\":109,\"dis\":6902}],\"eSd\":1,\"trafficLightDetails\":[{\"travelTime\":38,\"segIndex\":0},{\"travelTime\":38,\"segIndex\":3},{\"travelTime\":46,\"segIndex\":8},{\"travelTime\":41,\"segIndex\":12},{\"travelTime\":38,\"segIndex\":23},{\"travelTime\":8,\"segIndex\":40},{\"travelTime\":31,\"segIndex\":60},{\"travelTime\":38,\"segIndex\":70},{\"travelTime\":49,\"segIndex\":89}],\"desc\":\"大屯路\"},\"camera\":{\"ver\":\"2.4.57\",\"code\":100,\"cmrs\":[{\"pos\":\"gNAYF+xA0Ac=\",\"ty\":3,\"dis\":31},{\"pos\":\"ALwYF7RA0Ac=\",\"ty\":3,\"dis\":603},{\"pos\":\"qLoYF7BA0Ac=\",\"ty\":112,\"dis\":623},{\"pos\":\"6LIYF6BA0Ac=\",\"ty\":3,\"dis\":827},{\"pos\":\"sKgYF2RA0Ac=\",\"ty\":2,\"dis\":1112},{\"pos\":\"nKgYF9hI0Ac=\",\"ty\":112,\"dis\":1450},{\"pos\":\"kKgYF6xM0Ac=\",\"ty\":2,\"dis\":1582},{\"pos\":\"8KgYF9BM0Ac=\",\"ty\":132,\"dis\":1610},{\"pos\":\"LLQYF/xM0Ac=\",\"ty\":8,\"dis\":1894},{\"pos\":\"KLgYFwhO0Ac=\",\"vanSdLt\":60,\"sdLt\":60,\"dis\":2001},{\"pos\":\"oLoYFxBO0Ac=\",\"vanSdLt\":60,\"sdLt\":60,\"dis\":2083},{\"pos\":\"iMIYFyxO0Ac=\",\"vanSdLt\":60,\"sdLt\":60,\"dis\":2295},{\"pos\":\"lNgYF4RO0Ac=\",\"ty\":3,\"dis\":2897},{\"pos\":\"wNgYF4hO0Ac=\",\"vanSdLt\":60,\"sdLt\":60,\"dis\":2907},{\"pos\":\"8OAYF6RO0Ac=\",\"vanSdLt\":60,\"sdLt\":60,\"dis\":3137},{\"pos\":\"4OgYF7xO0Ac=\",\"vanSdLt\":60,\"sdLt\":60,\"dis\":3351},{\"pos\":\"bP4YF7RW0Ac=\",\"vanSdLt\":60,\"sdLt\":70,\"dis\":4187},{\"pos\":\"KBoaF1B00Ac=\",\"ty\":8,\"timeSpans\":\"17374887366436585472-127403928-0,17464959359002869760-127403928-0\",\"dis\":5882}]}}],\"supportRouteForecast\":true,\"dataVersion\":\"NavInfo.2020.06\",\"guidanceVersion\":3000,\"guid\":\"be95af5f6f6d91438201766c5f2dde1c\",\"timeDistribution\":{\"totalDuration\":139,\"highwayGuideCalculation\":0,\"sortProfileCalculation\":1,\"etaCalculation\":13,\"segmentPropertyExtraction\":0,\"basicRoutingCalculation\":103,\"removePoorRouteCalculation\":1,\"maneuverCalculation\":14},\"cameraVersion\":2}");
        } else if (mRouteType == 1) {
            mNaviSession.calculateWalkRoute(newstartPoint, newendPoint);
        } else if (mRouteType == 2) {
            VehicleInfo info = new VehicleInfo();
            info.width = 4.1f;
            info.height = 5.0f;
            info.purpose = VehicleInfo.PurposeType.truck;
            RoutePlan routePlan = new RoutePlan();
            routePlan.setRoutePreference(mNaviIndex);
            routePlan.setVehicleInfo(info);
            routePlan.setTransportationType(RoutePlan.TransportationType.truck);
            mNaviSession.calculateDriveRoute(newstartPoint, wayPoints, newendPoint, routePlan, NaviSession.RouteMethod.multipleResult);
        }
    }

    /**
     * 加载路线详情
     */
    public boolean loadRouteDetail() {
        if (mRouteBase != null) {
            if (mHadRouteDetailBrowser != null) {
                mHadRouteDetailBrowser.removeRouteDetailBrowserLoadedListener(mHadRouteDetailBrowserLoadedListener);
                mHadRouteDetailBrowser.release();
            }
            mHadRouteDetailBrowser = new HadRouteDetailBrowser(mRouteBase);
            mHadRouteDetailBrowser.addRouteDetailBrowserLoadedListener(mHadRouteDetailBrowserLoadedListener);
            mHadRouteDetailBrowser.loadMore(1000);
            return true;
        }

        return false;
    }

    public void endNavi() {
        mIsInNavigation = false;

        if (mRouteBase != null) {
            if (mNaviSession.isInSimulation()) {
                mNaviSession.pauseSimulation();
                mNaviSession.endSimulation();
            } else if (mIsInNavigation) {
                mNaviSession.removeRoute();
                mRouteBase = null;
                mRouteCollection = null;
            }

            Rect boundingBox = mRouteBase.getBoundingBox();
            Rect rect = new Rect(200, 350, ScreenUtil.getInstance().getScreenWidth() - 200,
                    ScreenUtil.getInstance().getScreenHeight() - 200);
            mMapPresenter.getMineMap().fitWorldAreaToRect(boundingBox, rect);
            mMapPresenter.getMineMap().setElevation(0);

            mMapPresenter.deleteNavingCar();
            mMapPresenter.deleteNaviCompassOverlay();
            mMapPresenter.deleteNavigateArrow();
        }
    }

    /**
     * 导航信息更新监听
     */
    private NaviProgressMonitor.NaviProgressUpdatedListener mNaviProgressUpdatedListener =
            new NaviProgressMonitor.NaviProgressUpdatedListener() {
                @Override
                public void onDataUpdated(NaviProgressData naviProgressData) {
                    mOnNaviPresenterListener.onDataUpdated(naviProgressData);
                }

                @Override
                public void onTiBarUpdated(final TmcSections tmcSections) {
                    mOnNaviPresenterListener.onTiBarUpdated(tmcSections);
                }
            };

    /**
     * 导航引导信息更新监听
     */
    private GuidanceTextGenerator.GuidanceTextGeneratorChangedListener
            mGuidanceTextGeneratorChangedListener =
            new GuidanceTextGenerator.GuidanceTextGeneratorChangedListener() {
                @Override
                public void onTextChanged(GuidanceText guidanceText) {
                    mOnNaviPresenterListener.onTextChanged(guidanceText);
                }

                @Override
                public void onDistanceChanged(int distance) {
                    mOnNaviPresenterListener.onDistanceChanged(distance);
                }
            };

    /**
     * 路线详情信息加载监听
     */
    private HadRouteDetailBrowser.HadRouteDetailBrowserLoadedListener mHadRouteDetailBrowserLoadedListener = new HadRouteDetailBrowser.HadRouteDetailBrowserLoadedListener() {
        @Override
        public void onHadRouteDetailBrowserLoaded(int beforeLoadedNum, int newLoadedNum, boolean mayHasMore) {
            int loadedDetailItemNumber = mHadRouteDetailBrowser.getLoadedDetailItemNumber();

            mRouteDetailItems = new ArrayList<>();

            for (int i = 0; i < loadedDetailItemNumber; i++) {
                mRouteDetailItems.add(mHadRouteDetailBrowser.getDetailItemAtIndex(i));
            }

            mOnNaviPresenterListener.onRouteDetailBrowserLoaded(mRouteDetailItems);
        }
    };

    MineNaviProgressManager.OnMineNaviProgressListener mOnMineNaviProgressListener = new MineNaviProgressManager.OnMineNaviProgressListener() {
        @Override
        public void onCalculateRouteSuccess(RouteCollection data) {
            // 获取路线规划信息
            mRouteCollection = data;
            // 获取单条道路信息
            mRouteBase = mRouteCollection.routes[0];
            // 获取路线
            //mNaviSession.takeRoute(mRouteBase);
            mMapPresenter.drawRoute(mRouteBase);
            mMapPresenter.showDestinationLabel(mRouteBase);
            // 语音播报
            NaviSpeaker.enqueue("路线规划完毕");

            Rect rect = new Rect(200, 350, ScreenUtil.getInstance().getScreenWidth() - 200,
                    ScreenUtil.getInstance().getScreenHeight() - 200);
            Rect boundingBox = mRouteBase.getBoundingBox();
            mMapPresenter.getMineMap().fitWorldAreaToRect(boundingBox, rect);

            mOnNaviPresenterListener.onCalculateRouteSuccess(mRouteBase);
        }

        @Override
        public void onCalculateRouteFailed(RouterErrorInfo data) {
            RouterErrorInfo re = data;
            Log.e(TAG, re.errCode + "");
            String msg = null;
            switch (re.errCode) {
                case RouterErrorInfo.Type.ComputeFailed:
                    msg = "路线计算失败";
                    break;
                case RouterErrorInfo.Type.destAuthError:
                    msg = "终点所在位置数据授权错误";
                    break;
                case RouterErrorInfo.Type.destNoData:
                    msg = "重点所在位置没有数据";
                    break;
                case RouterErrorInfo.Type.MissingSubfiles:
                    msg = "缺少途径省份数据";
                    break;
                case RouterErrorInfo.Type.NetworkError:
                    msg = "网络连接错误";
                    break;
                case RouterErrorInfo.Type.None:
                    // 没有错误信息
                    break;
                case RouterErrorInfo.Type.NotEnoughMemory:
                    msg = "没有足够的内存可以使用";
                    break;
                case RouterErrorInfo.Type.oriAuthError:
                    msg = "起点所在位置数据授权错误";
                    break;
                case RouterErrorInfo.Type.OriDestTooNear:
                    msg = "起点和终点距离太近";
                    break;
                case RouterErrorInfo.Type.oriNoData:
                    msg = "起点所在位置没有数据";
                    break;
                case RouterErrorInfo.Type.SetDestFailed:
                    msg = "设置终点失败";
                    break;
                case RouterErrorInfo.Type.SetOriFailed:
                    msg = "设置起点失败";
                    break;
                case RouterErrorInfo.Type.waypointAuthError:
                    msg = "途经点所在位置数据授权错误";
                    break;
                case RouterErrorInfo.Type.waypointNoData:
                    msg = "途经点所在位置没有数据";
                    break;
            }

            NaviSpeaker.enqueue("路线规划失败");
            mOnNaviPresenterListener.onCalculateRouteFailed(msg);
        }

        @Override
        public void onArriveDestination() {
            if (mIsInNavigation) {
                Rect rect = new Rect(200, 350, ScreenUtil.getInstance().getScreenWidth() - 200,
                        ScreenUtil.getInstance().getScreenHeight() - 200);
                Rect boundingBox = mRouteBase.getBoundingBox();
                mMapPresenter.getMineMap().fitWorldAreaToRect(boundingBox, rect);
                mMapPresenter.getMineMap().setElevation(0);
                mMapPresenter.deleteNavingCar();
                mMapPresenter.deleteNaviCompassOverlay();
                mIsInNavigation = false;
            }

            mOnNaviPresenterListener.onArriveDestination();
        }

        @Override
        public void onNewArrow(ArrowInfo arrowInfo) {
            if (mRouteType == 1) {
                return;
            }

            if (mIsInNavigation) {
                mMapPresenter.drawNavigateArrow(arrowInfo);
            }
        }

        @Override
        public void onDeleteArrow() {
            mMapPresenter.deleteNavigateArrow();
        }

        @Override
        public void onRerouteComplete(RouteBase data) {
            mMapPresenter.deleteRoute();
            mRouteBase = data;
            mMapPresenter.drawRoute(data);
        }

        @Override
        public void onRerouteFailed(RouterErrorInfo data) {
            RouterErrorInfo re = data;
            Log.e(TAG, re.errCode + "");
            String msg = null;
            switch (re.errCode) {
                case RouterErrorInfo.Type.ComputeFailed:
                    msg = "路线计算失败";
                    break;
                case RouterErrorInfo.Type.destAuthError:
                    msg = "终点所在位置数据授权错误";
                    break;
                case RouterErrorInfo.Type.destNoData:
                    msg = "重点所在位置没有数据";
                    break;
                case RouterErrorInfo.Type.MissingSubfiles:
                    msg = "缺少途径省份数据";
                    break;
                case RouterErrorInfo.Type.NetworkError:
                    msg = "网络连接错误";
                    break;
                case RouterErrorInfo.Type.None:
                    // 没有错误信息
                    break;
                case RouterErrorInfo.Type.NotEnoughMemory:
                    msg = "没有足够的内存可以使用";
                    break;
                case RouterErrorInfo.Type.oriAuthError:
                    msg = "起点所在位置数据授权错误";
                    break;
                case RouterErrorInfo.Type.OriDestTooNear:
                    msg = "起点和终点距离太近";
                    break;
                case RouterErrorInfo.Type.oriNoData:
                    msg = "起点所在位置没有数据";
                    break;
                case RouterErrorInfo.Type.SetDestFailed:
                    msg = "设置终点失败";
                    break;
                case RouterErrorInfo.Type.SetOriFailed:
                    msg = "设置起点失败";
                    break;
                case RouterErrorInfo.Type.waypointAuthError:
                    msg = "途经点所在位置数据授权错误";
                    break;
                case RouterErrorInfo.Type.waypointNoData:
                    msg = "途经点所在位置没有数据";
                    break;
            }

            NaviSpeaker.enqueue("路线规划失败");
            mOnNaviPresenterListener.onRerouteFailed(msg);
        }

        @Override
        public void onNaviBegin() {
            mOnNaviPresenterListener.onNaviBegin();
        }

        @Override
        public void onSimNaviBegin() {
            mOnNaviPresenterListener.onSimNaviBegin();
        }

        @Override
        public void onSimNaviEnd() {
            if (mIsInNavigation) {
                Rect rect = new Rect(200, 350, ScreenUtil.getInstance().getScreenWidth() - 200,
                        ScreenUtil.getInstance().getScreenHeight() - 200);
                Rect boundingBox = mRouteBase.getBoundingBox();
                mMapPresenter.getMineMap().fitWorldAreaToRect(boundingBox, rect);
                mMapPresenter.getMineMap().setElevation(0);
                mMapPresenter.deleteNavingCar();
                mMapPresenter.deleteNaviCompassOverlay();
                mIsInNavigation = false;
            }

            mOnNaviPresenterListener.onSimNaviEnd();
        }

        @Override
        public void onTracking(NaviSessionData data) {
            mOnNaviPresenterListener.onTracking((float) data.travelledDistance / data.routeLength);
        }

        @Override
        public void onSmoothTracking(SmoothNaviData data) {
            if (mIsInNavigation) {
                float carHeading = data != null ? data.carHeading : mRouteBase.getStartDirection();
                float mapHeading = data != null ? data.mapHeading : 0;

                mMapPresenter.showNavingCarPosition(data.carPos, carHeading);
                mMapPresenter.getMineMap().setHeading(mapHeading);
                mMapPresenter.getMineMap().setElevation(50.0f);
                mMapPresenter.getMineMap().setFovy(35);
                mMapPresenter.getMineMap().setViewShiftXY(0, 0.55f);
                mMapPresenter.getMineMap().setNdsPointToCenter(data.carPos.x, data.carPos.y);
                mMapPresenter.setAutoZoomLevel();
            }
        }
    };

    @Override
    public void onGPSEvent(int event, Object data) {
        switch (event) {
            case GpsTracker.GPSEvent.disconnected:
                break;
            case GpsTracker.GPSEvent.connected:
                mOnNaviPresenterListener.onGpsConnected();
                break;
        }
    }
}
